﻿#include "Ngay.h"
#include <iostream>
using namespace std;

// Phuong thuc khoi tao
Ngay::Ngay()
{
	_gio = 0;
	_ngay = 0;
	_thang = 0;
	_nam = 0;
}

Ngay::Ngay(int gio, int ngay, int thang, int nam)
{
	Ngay kq;
	kq._gio = gio;
	kq._ngay = ngay;
	kq._thang = thang;
	kq._nam = nam;
	if(!kq.KiemTraNgayThangNam())
	{
		//cerr << "Du lieu khong hop le. Vui long kiem tra lai\n";
		exit(1);
	}
	_gio = gio;
	_ngay = ngay;
	_thang = thang;
	_nam = nam;
}

Ngay:: ~Ngay()
{

}

void Ngay::init(int gio, int ngay, int thang, int nam)
{
	Ngay kq;
	kq._gio = gio;
	kq._ngay = ngay;
	kq._thang = thang;
	kq._nam = nam;
	if(!kq.KiemTraNgayThangNam())
	{
		//cerr << "Du lieu khong hop le. Vui long kiem tra lai\n";
		exit(1);
	}
	_gio = gio;
	_ngay = ngay;
	_thang = thang;
	_nam = nam;
}

// Phuong thuc nhap
void Ngay::Nhap()
{
	do
	{
		cout << "Nhap gio : ";
		cin >> _gio;
		cout << "Nhap ngay : ";
		cin >> _ngay;
		cout << "Nhap thang : ";
		cin >> _thang;
		cout << "Nhap nam : ";
		cin >> _nam;
	} while(this->KiemTraNgayThangNam() == false);
}

// Phuong thuc kiem tra
bool Ngay::KiemTraNgayThangNam()
{
	int nhuan = 0;
	if(_gio < 0 || _gio > 23)

	if(_ngay <= 0 || _thang <= 0 || _nam <= 0)
	{
		cout << "Ngay thang nam khong hop le. Vui long kiem tra lai\n";
		return false;
	}

	if(_nam % 400 == 0 || (_nam % 4 == 0 && _nam % 100 != 0))
	{
		nhuan = _nam;
	}
	if(_thang == 2 && _nam == nhuan && _ngay > 29)
	{
		cout << "Thang " << _thang << " nam " << _nam << " chi co 29 ngay. Vui long kiem tra lai\n";
		return false;
	}
	if(_thang == 2 && _nam != nhuan && _ngay > 28)
	{
		cout << "Thang " << _thang << " nam " << _nam << " chi co 28 ngay. Vui long kiem tra lai\n";
		return false;
	}
	if( (_thang == 1 || _thang == 3 || _thang == 5 || _thang == 7 || _thang == 8 || _thang == 10 || _thang == 12) && _ngay > 31)
	{
		cout << "Thang " << _thang << " nam " << _nam << " chi co 31 ngay. Vui long kiem tra lai\n";
		return false;
	}
	if( (_thang == 4 || _thang == 6 || _thang == 9 || _thang == 11) && _ngay > 30)
	{
		cout << "Thang " << _thang << " nam " << _nam << " chi co 30 ngay. Vui long kiem tra lai\n";
		return false;
	}
	if(_thang > 12)
	{
		cout << "Mot nam chi co 12 thang. Vui long kiem tra lai\n";
		return false;
	}
}

// Phuong thuc xuat
void Ngay::Xuat()
{
	cout << _ngay << " / " << _thang << " / " << _nam << endl;
}

// Phuong thuc tinh ngay ke tiep
Ngay Ngay::NgayKeTiep()
{
	Ngay kq;

	int nhuan = 0;
	if(_nam % 400 == 0 || (_nam % 4 == 0 && _nam % 100 != 0))
	{
		nhuan = _nam;
	}

	if( (_ngay == 29 && _thang == 2 && _nam == nhuan) || (_ngay == 28 && _thang == 2 && _nam != nhuan) )
	{
		kq._ngay = 1;
		kq._thang = 3;
		kq._nam = _nam;
	}
	else if( _ngay == 31 && (_thang == 1 || _thang == 3 || _thang == 5 || _thang == 7 || _thang == 8 || _thang == 10) )
	{
		kq._ngay = 1;
		kq._thang = _thang + 1;
		kq._nam = _nam;
	}
	else if(_ngay == 31 && _thang == 12)
	{
		kq._ngay = 1;
		kq._thang = 1;
		kq._nam = _nam + 1;
	}
	else if(_ngay == 30 && (_thang == 4 || _thang == 6 || _thang == 9 || _thang == 11) )
	{
		kq._ngay = 1;
		kq._thang = _thang + 1;
		kq._nam = _nam;
	}
	else
	{
		kq._ngay = _ngay + 1;
		kq._thang = _thang;
		kq._nam = _nam;
	}
	return kq;
}

Ngay Ngay::NgayHomQua()
{
	Ngay kq;

	int nhuan = 0;
	if(_nam % 400 == 0 || (_nam % 4 == 0 && _nam % 100 != 0))
	{
		nhuan = _nam;
	}

	if( (_ngay == 1 && _thang == 3 && _nam == nhuan) )
	{
		kq._ngay = 29;
		kq._thang = 2;
		kq._nam = _nam;
	}
	else if( (_ngay == 1 && _thang == 3 && _nam != nhuan) )
	{
		kq._ngay = 28;
		kq._thang = 2;
		kq._nam = _nam;
	}
	else if(_ngay == 1 && (_thang == 5 || _thang == 7 || _thang == 10 || _thang == 12) )
	{
		kq._ngay = 30;
		kq._thang = _thang - 1;
		kq._nam = _nam;
	}
	else if( _ngay == 1 && (_thang == 2 || _thang == 4 || _thang == 6 || _thang == 8 || _thang == 9 || _thang == 11) )
	{
		kq._ngay = 31;
		kq._thang = _thang - 1;
		kq._nam = _nam;
	}
	else if(_ngay == 1 && _thang == 1)
	{
		kq._ngay = 31;
		kq._thang = 12;
		kq._nam = _nam - 1;
	}
	else
	{
		kq._ngay = _ngay - 1;
		kq._thang = _thang;
		kq._nam = _nam;
	}
	return kq;
}

// Phuong thuc so sanh 2 ngay
// Tra ve 0 neu 2 ngay giong nhau
// Tra ve -1 neu (ngay thu 1) truoc (ngay thu 2)
// Tra ve 1 neu (ngay thu 1) sau (ngay thu 2)
int Ngay::SoSanh(Ngay d)
{
	if(_ngay == d._ngay && _thang == d._thang && _nam == d._nam)
		return 0;
	if(_nam == d._nam)
	{
		if(_thang == d._thang)
		{
			if(_ngay < d._ngay)
				return -1;
			else
				return 1;
		}
		else if(_thang < d._thang)
			return -1;
		else
			return 1;
	}
	else if(_nam < d._nam)
		return -1;
	else
		return 1;
}

// Phương thức tính ngày thứ mấy trong năm
int Ngay::NgayTrongNam()
{
	int kq = 0;

	int nhuan = 0;
	if(_nam % 400 == 0 || (_nam % 4 == 0 && _nam % 100 != 0))
	{
		nhuan = _nam;
	}

	for(int i = 1 ; i < _thang ; i++)
	{
		if(i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12)
			kq += 31;
		if(i == 2 && _nam == nhuan)
			kq += 29;
		if(i == 2 && _nam != nhuan)
			kq += 28;
		if(i == 4 || i == 6 || i == 9 || i == 11)
			kq += 30;
	}
	kq += _ngay;
	return kq;
}

// Phương thức tính ngày trước (ngày vừa nhập) k ngày
Ngay Ngay::TruocKNgay(int k)
{
	Ngay kq;
	kq._ngay = _ngay;
	kq._thang = _thang;
	kq._nam = _nam;
	for(int i = 1 ; i <= k ; i++)
		kq = kq.NgayHomQua();
	return kq;
}

// Phương thức tính ngày sau (ngày vừa nhập) k ngày
Ngay Ngay::SauKNgay(int k)
{
	Ngay kq;
	kq._ngay = _ngay;
	kq._thang = _thang;
	kq._nam = _nam;
	for(int i = 1 ; i <= k ; i++)
		kq = kq.NgayKeTiep();
	return kq;
}


int Ngay::KhoangCachNgay(Ngay d)
{
	int kq = 0;
	int i;

	int nhuan = 0;
	if(_nam % 400 == 0 || (_nam % 4 == 0 && _nam % 100 != 0))
	{
		nhuan = _nam;
	}
	
	if(_nam == d._nam)
	{
		if(_thang < d._thang)
		{
			// Tinh thang hien tai con bao nhieu ngay
			if(_thang == 1 || _thang == 3 || _thang == 5 || _thang == 7 || _thang == 8 || _thang == 10 || _thang == 12)
				kq += (31 - _ngay);
			if(_thang == 2 && _nam == nhuan)
				kq += (29 - _ngay);
			if(_thang == 2 && _nam != nhuan)
				kq += (28 - _ngay);
			if(_thang == 4 || _thang == 6 || _thang == 9 || _thang == 11)
				kq += (30 - _ngay);

			// Tinh so ngay tu (thang_hien_tai + 1) den (thang_can_tinh - 1)
			for(i = _thang+1 ; i < d._thang ; i++)
			{
				if(i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12)
					kq += 31;
				if(i == 2 && _nam == nhuan)
					kq += 29;
				if(i == 2 && _nam != nhuan)
					kq += 28;
				if(i == 4 || i == 6 || i == 9 || i == 11)
					kq += 30;
			}
			
			// Cong them so ngay cua ngay thang can tinh
			kq += d._ngay;
		}
		else if(_thang == d._thang)
		{
			kq = abs(_ngay - d._ngay);
		}
		else // thang hien tai > thang can tinh
		{
			Ngay tam;
			tam._ngay = _ngay;
			tam._thang = _thang;
			tam._nam = _nam;
			kq = d.KhoangCachNgay(tam);
		}
	}
	else if(_nam < d._nam) // năm hiện tại < năm cần tính
	{
		// Tinh so ngay con lai cua nam hien tai
		for(i = _thang+1 ; i <= 12 ; i++) // Tinh so ngay tu (thang hien tai + 1) den thang 12
		{
			nhuan = 0;
			if(_nam % 400 == 0 || (_nam % 4 == 0 && _nam % 100 != 0))
			{
				nhuan = _nam;
			}
			if(i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12)
				kq += 31;
			if(i == 2 && _nam == nhuan)
				kq += 29;
			if(i == 2 && _nam != nhuan)
				kq += 28;
			if(i == 4 || i == 6 || i == 9 || i == 11)
				kq += 30;
		}
		// Cong them so ngay con lai cua thang hien tai
		if(_thang == 1 || _thang == 3 || _thang == 5 || _thang == 7 || _thang == 8 || _thang == 10 || _thang == 12)
			kq += (31 - _ngay);
		if(_thang == 2 && _nam == nhuan)
			kq += (29 - _ngay);
		if(_thang == 2 && _nam != nhuan)
			kq += (28 - _ngay);
		if(_thang == 4 || _thang == 6 || _thang == 9 || _thang == 11)
			kq += (30 - _ngay);

		// Tinh so ngay tu (nam hien tai + 1) den (nam can tinh - 1)
		for(i = _nam+1 ; i < d._nam ; i++)
		{
			nhuan = 0;
			if(i % 400 == 0 || (i % 4 == 0 && i % 100 != 0))
			{
				nhuan = i;
			}
			if(i == nhuan)
				kq += 366;
			else
				kq += 365;
		}

		// Tinh so ngay tu dau nam can tinh den ngay thang nam can tinh
		for(i = 1 ; i < d._thang ; i++) // Tinh so ngay tu thang 1 den (thang can tinh - 1)
		{
			nhuan = 0;
			if(d._nam % 400 == 0 || (d._nam % 4 == 0 && d._nam % 100 != 0))
			{
				nhuan = d._nam;
			}
			if(i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12)
				kq += 31;
			if(i == 2 && d._nam == nhuan)
				kq += 29;
			if(i == 2 && d._nam != nhuan)
				kq += 28;
			if(i == 4 || i == 6 || i == 9 || i == 11)
				kq += 30;
		}
		kq += d._ngay; // cong them so ngay cua thang can tinh
	}
	else // năm hiện tại > năm cần tính
	{
		Ngay tam;
		tam._ngay = _ngay;
		tam._thang = _thang;
		tam._nam = _nam;
		kq = d.KhoangCachNgay(tam);
	}

	return kq;
}

int Ngay::KhoangCachThang(Ngay d)
{
	int kq = 0;

	if(_nam == d._nam)
	{		
		if(_thang < d._thang)
		{
			kq = d._thang - _thang;
			if(_ngay > d._ngay) // 28/01 va 01/03
				kq--;
		}
		else if(_thang > d._thang)
		{
			kq = _thang - d._thang;
			if(_ngay < d._ngay) // 01/03 va 28/01
				kq--;
		}
		else kq = 0;
	}
	else if(_nam < d._nam) // 20/10/2010 va 10/01/2012
	{
		kq = (d._nam - _nam - 1) * 12;
		kq += 12 - _thang;
		kq += d._thang;
		if(_ngay > d._ngay) // 20/10/2010 va 10/01/2011
			kq--;

	}
	else // 10/01/2012 va 20/10/2010
	{
		kq = (_nam - d._nam - 1) * 12;
		kq += 12 - d._thang;
		kq += _thang;
		if(_ngay < d._ngay) // 10/01/2011 va 20/10/2010
			kq--;
	}

	return kq;
}

int Ngay::KhoangCachNam(Ngay d)
{
	int kq = 0;

	if(_nam < d._nam) // 20/05/2000 va 10/02/2010
	{
		kq = d._nam - _nam;
		if(d._thang < _thang || (_thang == d._thang && d._ngay < _ngay))
			kq--;
	}
	else if(_nam > d._nam) // 10/02/2010 va 20/05/2000
	{
		kq = _nam - d._nam;
		if(_thang < d._thang || (_thang == d._thang && _ngay < d._ngay))
			kq--;
	}
	else
		kq = 0;
	return kq;
}

int Ngay::getNam()
{
	return _nam;
}

int Ngay::getThang()
{
	return _thang;
}

int Ngay::getNgay()
{
	return _ngay;
}

void Ngay::setNam(int nam)
{
	_nam = nam;
}

void Ngay::setThang(int thang)
{
	_thang = thang;
}

void Ngay::setNgay(int ngay)
{
	_ngay = ngay;
}